package org.acghub.mtdb.core.log.impl;

import org.acghub.mtdb.core.LogKey;
import org.acghub.mtdb.core.log.LogAbstractSet;

import java.util.Comparator;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.SortedSet;

public final class LogTreeSet<E> extends LogAbstractSet<E> implements NavigableSet<E> {
    public LogTreeSet(LogKey logkey, NavigableSet<E> wrapped) {
        super(logkey, wrapped);
    }

    private LogTreeSet(LogTreeSet<E> root, NavigableSet<E> wrapped) {
        super(root, wrapped);
    }

    private LogTreeSet(LogTreeSet<E> root, SortedSet<E> wrapped) {
        super(root, wrapped);
    }

    @Override
    public E lower(E e) {
        return wrapped().lower(e);
    }

    @Override
    public E floor(E e) {
        return wrapped().floor(e);
    }

    @Override
    public E ceiling(E e) {
        return wrapped().ceiling(e);
    }

    @Override
    public E higher(E e) {
        return wrapped().higher(e);
    }

    @Override
    public E pollFirst() {
        onChange();
        E e = wrapped().pollFirst();
        onRemove(e);
        return e;
    }

    @Override
    public E pollLast() {
        onChange();
        E e = wrapped().pollLast();
        onRemove(e);
        return e;
    }

    @Override
    public NavigableSet<E> descendingSet() {
        return new LogTreeSet<>(this, wrapped().descendingSet());
    }

    @Override
    public Iterator<E> descendingIterator() {
        return new LogIte(wrapped().descendingIterator());
    }

    @Override
    public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
        return new LogTreeSet<>(this, wrapped().subSet(fromElement, fromInclusive, toElement, toInclusive));
    }

    @Override
    public NavigableSet<E> headSet(E toElement, boolean inclusive) {
        return new LogTreeSet<>(this, wrapped().headSet(toElement, inclusive));
    }

    @Override
    public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
        return new LogTreeSet<>(this, wrapped().tailSet(fromElement, inclusive));
    }

    @Override
    public Comparator<? super E> comparator() {
        return sortedWrapped().comparator();
    }

    @Override
    public SortedSet<E> subSet(E fromElement, E toElement) {
        return new LogTreeSet<>(this, sortedWrapped().subSet(fromElement, toElement));
    }

    @Override
    public SortedSet<E> headSet(E toElement) {
        return new LogTreeSet<>(this, sortedWrapped().headSet(toElement));
    }

    @Override
    public SortedSet<E> tailSet(E fromElement) {
        return new LogTreeSet<>(this, sortedWrapped().tailSet(fromElement));
    }

    @Override
    public E first() {
        return wrapped().first();
    }

    @Override
    public E last() {
        return wrapped().last();
    }

    @Override
    protected NavigableSet<E> wrapped() {
        return (NavigableSet<E>) wrapped;
    }

    private SortedSet<E> sortedWrapped() {
        return (SortedSet<E>) wrapped;
    }

}
